/* =======================================================================
 * Sistemi Operativi, Corso di Laurea in Ingegneria Informatica, DM 270/04
 * A.A. 2011/2012, Facoltà di Ingegneria, Università della Calabria
 * =======================================================================
 */

package sisop.appelli.a2012.treaule;

/**
 * @author Marco Lackovic <mlackovic@deis.unical.it>
 * @version 1.0, Jul 27, 2012
 */
public abstract class Aule {

	public static final int NUMERO_AULE = 3;
	public static final int[] MAX_POSTI = { 80, 60, 40 };

	/*
	 * Questo intero serve per sapere quando sospendere il docente nel caso in
	 * cui si esauriscano i posti disponibili.
	 */
	protected int totalePostiDisponibili = 0;

	// Questo intero memorizza l'id dell'aula da assegnare al prossimo studente.
	protected int aulaProssimoStudente;

	// Questo array memorizza il numero di sposti disponibili in ciascuna aula.
	protected int[] postiDisponibili = MAX_POSTI;

	public Aule() {
		for (int i = 0; i < MAX_POSTI.length; i++) {
			totalePostiDisponibili += MAX_POSTI[i];
		}
	}

	/*
	 * Questo metodo serve per trovare l'id dell'aula da assegnare al prossimo
	 * studente in modalità round-robin e per decrementare il numero di posti
	 * disponibili nell'aula scelta. Prima di essere invocato si deve avere la
	 * certezza che esista almeno un posto disponibile in un'aula qualsiasi.
	 */
	protected void aggiornaAule() {
		aulaProssimoStudente = (aulaProssimoStudente + 1) % NUMERO_AULE;
		while (postiDisponibili[aulaProssimoStudente] == 0) {
			aulaProssimoStudente = (aulaProssimoStudente + 1) % NUMERO_AULE;
		}
		postiDisponibili[aulaProssimoStudente]--;
	}

	public abstract int accedi() throws InterruptedException;

	public abstract void esci(int aula) throws InterruptedException;

	public abstract void chiamaStudente() throws InterruptedException;
}
